<?php
/**
 * DotHerbert
 *
 * @package    UnitTest
 * @copyright  2009 extreme-programmers
 * @license    http://dotherbert.extreme-programmers.com/license   BSD License
 * @version    $Id: TestSuiteLoader.php 108 2009-05-13 19:09:31Z johannes.trink@extreme-programmers.com $
 */

namespace dotherbert\unittest;

/**
 * TestSuite loader
 *
 * @package    UnitTest
 * @author     Johannes Trink <johannes.trink@extreme-programmers.com>
 */
class TestSuiteLoader
{
    /**
     * Main methods
     *
     * @var array
     */
    private static $mainMethods = array();

    /**
     * Get unit test main method
     *
     * @return string
     */
    public static function getUnitTestMainMethod($file)
    {
        if (!isset(self::$mainMethods[$file])) {
            self::$mainMethods[$file] = self::getClassByAbsolutePath($file) . '::main';
        }
        return self::$mainMethods[$file];
    }

    /**
     * Run unit test main method
     *
     * @param  string $mainMethod
     * @return void
     */
    public static function runUnitTestMainMethod($mainMethod)
    {
        eval($mainMethod . '();');
    }

    /**
     * Get suite
     *
     * @param  string $file
     * @return PHPUnit_Framework_TestSuite
     */
    public static function getSuite($file)
    {
        $suite = new \PHPUnit_Framework_TestSuite();
        $suite->setName('Suite: ' . self::getClassByAbsolutePath($file));
        $directoryIterator = new \DirectoryIterator(dirname($file));

        $testCaseIterator = new TestCaseIterator($directoryIterator);
        foreach ($testCaseIterator as $testCaseFile) {
            require_once $testCaseFile->getPathname();
            $suite->addTestSuite(new \ReflectionClass(
                    self::getClassByAbsolutePath($testCaseFile->getPathname())
                ));
        }


        $directoryIterator = new \DirectoryIterator(dirname($file));
        $testDirectoryIterator = new TestDirectoryIterator($directoryIterator);
        foreach ($testDirectoryIterator as $testDirectory) {
            $path = $testDirectory->getPathname() . DIRECTORY_SEPARATOR . 'AllTests.php';
            require_once $path;
            $class = self::getClassByAbsolutePath($path);
            $subsuite = $class::suite();
            $suite->addTest($subsuite);
        }
        return $suite;
    }

    /**
     * Get class by absolute path
     *
     * @param string $file
     *
     * @return string
     */
    private static function getClassByAbsolutePath($file)
    {
        $testsPos = strrpos($file, DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR);
        $class = str_replace(DIRECTORY_SEPARATOR, '\\', substr($file, $testsPos + 7, -4));
        return $class;
    }
}